//
// Created by gushen610140 on 2024/3/28.
//

#include <iostream>

#ifndef DATASTRUCTURECOURSE_GSTRING_H
#define DATASTRUCTURECOURSE_GSTRING_H

class [[maybe_unused]] GString {
private:
    char *_data;
    int _length;

    const int max_length = 100;
public:
    [[maybe_unused]] explicit GString(char *s) {
        _data = s;
        _length = 0;
        while (s[_length] != '\0') {
            _length++;
        }
    };

    [[maybe_unused]] GString() {
        _data = new char[max_length];
        _length = 0;
    }

    [[maybe_unused]] [[nodiscard]] int length() const {
        return _length;
    }

    char operator[](int i) const {
        return _data[i];
    }

    bool operator==(const GString &other) const {
        if (_length != other._length) {
            return false;
        }
        for (int i = 0; i < _length; i++) {
            if (_data[i] != other._data[i]) {
                return false;
            }
        }
        return true;
    }

    bool operator<(const GString &other) const {
        int i = 0;
        while (i < _length && i < other._length) {
            if (_data[i] != other._data[i]) {
                return _data[i] < other._data[i];
            }
            i++;
        }
        return _length < other._length;
    }

    bool operator>(const GString &other) const {
        int i = 0;
        while (i < _length && i < other._length) {
            if (_data[i] != other._data[i]) {
                return _data[i] > other._data[i];
            }
            i++;
        }
        return _length > other._length;
    }

    // 友元函数，理解待提高
    friend std::ostream &operator<<(std::ostream &os, const GString &s) {
        for (int i = 0; i < s._length; i++) {
            os.put(s._data[i]);
        }
        return os;
    }

    friend std::istream &operator>>(std::istream &is, GString &s) {
        int i = 0;
        while (is.get(s._data[i])) {
            // if (s._data[i] == '!')
            if (s._data[i] == '\n' || s._data[i] == ' ') {
                break;
            }
            i++;
        }
        s._length = i;
        return is;
    }

    [[maybe_unused]] void cutFront(int start) {
        for (int i = start; i < _length; i++) {
            _data[i - start] = _data[i];
        }
        _length -= start;
    }

    [[maybe_unused]] void upper() {
        for (int i = 0; i < _length; i++) {
            if (_data[i] >= 'a' && _data[i] <= 'z') {
                _data[i] = _data[i] - 'a' + 'A';
            }
        }
    }

    [[maybe_unused]] void lower() {
        for (int i = 0; i < _length; i++) {
            if (_data[i] >= 'A' && _data[i] <= 'Z') {
                _data[i] = _data[i] - 'A' + 'a';
            }
        }
    }

    [[maybe_unused]] void reverse() {
        int begin = 0;
        int end = _length - 1;
        while (begin < end) {
            char temp = _data[begin];
            _data[begin] = _data[end];
            _data[end] = temp;
            begin++;
            end--;
        }
    }
};


#endif //DATASTRUCTURECOURSE_GSTRING_H
